#ifndef DATA_HPP
#define DATA_HPP

/*! \file data.hpp
 *
 *  \brief Definicja klasy Data.
 *
 *  Plik zawiera definicję klasy Data. Obiekt
 *  tej zawiera wszelkie pola i metody
 *  związane z obsługą zbiorów danych.
 *
 *  \author Karol Kurpanik
 *  \date 2010.04.04
 *  \version 2.20.10
 */

#include<QDir>
#include<QMatrix4x4>
#include<QString>

#include <fstream>

#include "bibstyle.hpp"
#include "graph.hpp"
#include "labels.hpp"
#include "set.hpp"

/*! \class Data
 *
 * \brief Klasa odpowiada za wszelkie operacje związane
 * z obsługą zbiorów danych.
 *
 * Klasa zawiera metody pozwalające na wczytanie danych
 * z pliku, utworzenie odpowiednich struktur danych do
 * przechowywania danych, a także operacje mające na celu
 * przeprowadzenie obróbki danych.
 */
class Data
{
public:
    /*!
     * \brief Konstruktor klasy Data.
     *
     * Konstruktor ustawiający domyślne wartości
     * atrybutów klasy.
     * \post Data::_Filename = "fast_2D_0.dat", \n
     * Data::_xvizPath = homePath()+"/.XViz".
     * \return void
     */
    Data();
    /*!
     * \brief Destruktor klasy Data.
     *
     * Usuwa wskaźnik Data::_Filename.
     * \return void
     */
    ~Data();
    /*!
     * \brief Metoda odpowiedzialna za wczytanie pliku
     * i utworzenie odpowiednich struktur danych.
     *
     * Zadaniem tej metody jest utworzenie kontenera do
     * przechowywania wczytanego pliku.
     * \post dane z pliku zostają umieszczone w zmiennej Data::_DataSet.
     * \return void
     */
    void ReadData();
    /*!
     * \brief Metoda odpowiedzialna na podział wczytanego
     * zbioru danych na podzbiory.
     *
     * Zadaniem tej metody jest przeprowadzenie analizy zbioru
     * danych pod kątem tego, czy zawiera więcej niż jeden blok
     * danych. Jeśli tak, metoda powoduje podział tego zbioru
     * i utworzenie odpowiednich struktur.
     * \post dane zostają umieszczone na wektorze Data::_DataSplitted.
     * \return void
     */
    void SplitData();
    /*!
     * \brief Metoda ustawiająca wartość pola przechowującego
     * nazwę pliku wejściowego.
     *
     * Metoda jest odpowiedzialna za wspisanie nazwy pliku
     * wejściowego, z którego są odczytywane dane, do zmiennej.
     * \param Filename - przechowuje nazwę pliku
     * \post Data::_Filename = Filename.
     * \return void
     */
    void setFileName(char* Filename);
    /*!
     * \brief Metoda zwracająca nazwę pliku wejściowego.
     *
     * Metoda pozwala na odczytanie wartości pola prywatnego
     * przechowującego nazwę pliku wejściowego. Zwrócona
     * zostaje wartość atrybutu Data::_Filename.
     * \return char *
     */
    char* getFileName();
    /*!
     * \brief Metoda generujące plik z danymi wejściowymi
     * dla nowego wykresu.
     *
     * Metoda tworzy plik wykorzystany przy generowaniu
     * nowego wykresu za pomoca Gnuplota.
     * \param Sets - zawiera wektor liczb naturalnych określających,
     * które bloki danych mają zostać dopisane do pliku.
     * \post zostaje utworzony plik data.xviz
     * \return void
     */
    void generateDataFile(vector<int> Sets);
    /*!
     * \brief Metoda generująca plik skryptowy dla gnuplota.
     *
     * Metoda tworzy nowy plik zawierający skrypt dla
     * gnuplota, na którego podstawie zostanie wygenerowany
     * nowy wykres.
     * \param bs - jest wskaźnikiem do biblioteki stylów,
     * \param ListOfCharts - wektor zawierający parametry wykresów, które
     * są przeznaczone do wyświetlenia,
     * \param labels - jest wskaźnikiem do obiekty zawierającego opis etykiet.
     * \post - zostaje utworzony plik plot.gplt
     * \return void
     */
    void generateScriptFile(BibStyle *bs, vector<Graph*> ListOfCharts, Labels* labels);
    /*!
     * \brief Metoda implementująca algorytm regresji liniowej.
     *
     * Metoda pozwala na wyznaczenie prostej najlepiej dopasowanej
     * do zbioru punktów metodą regresji liniowej. Zwraca
     * wektor zawierający parametry prostej (a i b).
     * \param Set - zawiera zbiór punktów w postaci napisów.
     * \return vector<float>
     */
    vector<float> linearRegression(vector<string> Set);
    /*!
     * \brief Metoda implementująca algorytm regresji kwadratowej.
     *
     * Metoda pozwala na wyznaczenie krzywej kwadratowej najlepiej
     * dopasowanj do zbioru punktów metodą regresji kwadratowej.
     * Zwraca wektor zawierający parametry krzeywej drugiego
     * stopnia (a,b,c)
     * \param Set - zawiera zbiór punktów w postaci napisów.
     * \return vector<float>
     */
    vector<float> quadraticRegression(vector<string> Set);
    /*!
     * \brief Metoda zwracająca minimalny element w wybranej
     * kolumnie.
     *
     * Metoda zwraca minimalną wartość w bloku danych o numerze
     * ID, w kolumnie o numerze ColNum.
     * \param ID - określa numer bloku danych,
     * \param ColNum - określa numer wybranej kolumny.
     * \return double
     */
    double minInCol(int ID, int ColNum);
    /*!
     * \brief Metoda zwracająca maksymalny element w wybranej
     * kolumnie.
     *
     * Metoda zwraca maksymalną wartość w bloku danych o numerze
     * ID, w kolumnie o numerze ColNum.
     * \param ID - określa numer bloku danych,
     * \param ColNum - określa numer wybranej kolumny.
     * \return double
     */
    double maxInCol(int ID, int ColNum);
    /*!
     * \brief Zwraca ilość kolumn w wybranym bloku danych.
     *
     * Zwraca ilość kolumn w bloku danych określonym numerem ID
     * \param ID - numer bloku danych
     * \return int
     */
    int numOfCols(int ID);
    /*!
     * \brief Zwraca ilość wierszy w wybranym bloku danych.
     *
     * Zwraca ilość wierszy w bloku danych określonym numerem ID
     * \param ID - numer bloku danych
     * \return int
     */
    int numOfRows(int ID);

    /*!
     * \brief Przechowuje dane podzielone na bloki.
     *
     * Pole zawierające podzielony zbiór danych. Zostaje
     * wypełnione danym w momencie wywołania metody
     * Data::SplitData()
     */
    vector<Set> _DataSplitted;
    /*!
     * \brief Przechowuje dane podzielone na bloki,
     * po dokonanej obróbce.
     *
     * Pole zawierające podzielony i obrobiony zbiór danych.
     */
    vector<Set> _DataProcessed;


private:
    /*!
     * \brief Przechowuje wczytany zbiór danych z pliku.
     *
     * Pole przechowuje wczytane plik w postaci wektora
     * napisów typu string. Każdy napis odpowiada
     * jednej linii z pliku.
     */
    vector<string> _DataSet;
    /*!
     * \brief Nazwa wczytywanego pliku.
     *
     * Pole zawiera nazwę pliku, z którego wczytywane
     * są dane.
     */
    char* _Filename;
    /*!
     * \brief Ścieżka do katalogu domyślnego aplikacji.
     *
     * Zmienna zawiera ścieżkę do katalogu domyślnego aplikacji
     * znajdującego się w katalogu domowym użytkownika.
     */
    QString _xvizPath;
    /*!
     * \brief Ilość linii w pliku.
     *
     * Zmienna przechowuje liczbę linii we wczytywanym pliku.
     */
    int _NumLines;

    /*!
     * \brief Metoda konwertująca wektor stringów na tablicę float.
     *
     * Metoda pozwalająca przekonwertować wektor napisów zawierający
     * dane na dwuwymiarową tablicę floatów.
     * \param DataSet - wektor zawierający dane w formie napisów string
     * \return vector< vector<float> >
     */
    vector< vector<float> > convVecStr2TabFloat(vector<string> DataSet);
};

#endif // DATA_HPP
